home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / CH_2.2 / HISTRAMP / HISTRAMP.C < prev    next >
C/C++ Source or Header  |  1999-09-11  |  6KB  |  214 lines

  1. /* 
  2.  * histramp.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* HISTRAMP: program performs histogram modification upon a b/w image
  10.  *         - yielding an image whose probability density fct is
  11.  *           ramp shaped
  12.  *              usage: histramp inimg outimg [-s SLOPE_SIGN] [-L]
  13.  *
  14.  *
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <math.h>
  21. #include <tiffimage.h>          /* tiff info on images */
  22. #include <images.h>             /* contains image format information */
  23. extern void print_sos_lic ();
  24.  
  25. #define NBINS 256               /* no. of histogram bins */
  26. #define MAX 255                 /* maximum value of histogram */
  27. #define MAXP1 256               /* no. histogram values */
  28. #define DFLT_SLOPE 0            /* default slope of intensity histogram */
  29.  
  30. int histdistr (long *, long, long *);
  31. int usage (short);
  32. int input (int, char **, long *);
  33.  
  34. main (argc, argv)
  35.      int argc;
  36.      char *argv[];
  37.  
  38. {
  39.   register int i, j;
  40.   register double constant;     /* a constant value */
  41.   Image *imgI;                  /* I/O image structures */
  42.   unsigned char **image,        /* input/output data array */
  43.     transform[MAXP1];           /* transform array */
  44.   long ntotal,                  /* total of summation of cumulative distr. */
  45.     distr[NBINS];               /* cumulative distribution array */
  46.   long hist[NBINS],             /* image histogram array */
  47.     nCol,                       /* image dimensions */
  48.     nRow, slopeSign;            /* sign of slope (-1, 0, +1 for -, 0, +) */
  49.   double intercept,             /* histogram 0-intercept */
  50.     slope;                      /* histogram slope */
  51.   double z;
  52.  
  53. /* read user parameter values */
  54.   if ((input (argc, argv, &slopeSign)) < 0)
  55.     return (-1);
  56.  
  57. /* invert slopeSign for white high, black low (added 13-Jul-99) */
  58.   if (slopeSign == -1)
  59.     slopeSign = 1;
  60.   else if (slopeSign == 1)
  61.     slopeSign = -1;
  62.  
  63. /* open input file */
  64.   imgI = ImageIn (argv[1]);
  65.   if (imgI->bps == 8 && imgI->spp == 3) {
  66.     printf ("Got RGB image!!!\nInput image must be Grayscale or B&W!!\n");
  67.     exit (1);
  68.   }
  69.   image = imgI->img;
  70.   nRow = ImageGetHeight (imgI);
  71.   nCol = ImageGetWidth (imgI);
  72.   printf ("image size is %dx%d\n", nCol, nRow);
  73.  
  74. /* construct histogram */
  75.   for (i = 0; i < NBINS; i++)
  76.     hist[i] = 0;
  77.   for (i = 0; i < nRow; i++)
  78.     for (j = 0; j < nCol; j++)
  79.       hist[image[i][j]]++;
  80.  
  81. /* construct cumumlative distribution */
  82.   histdistr (hist, NBINS, distr);
  83.  
  84. /* total summation under cumulative distribution omits 1/2 of lowest
  85.  * and highest occupied bins (See history note, 1 April 85) */
  86.   ntotal = distr[NBINS - 1];
  87.  
  88. /* calculate slope */
  89.  
  90.   switch (slopeSign) {
  91.   case -1:
  92.     slope = -2.0 * ntotal / (double) (MAX * MAX);
  93.     break;
  94.   case 0:
  95.     slope = 0.0;
  96.     break;
  97.   case 1:
  98.     slope = 2.0 * ntotal / (double) (MAX * MAX);
  99.     break;
  100.   }
  101.  
  102. /* compute transform table for histogram equalization or histogram ramp */
  103.  
  104.   switch (slopeSign) {
  105.  
  106.   case -1:                     /* negative ramp */
  107.     intercept = ntotal / (double) MAX - slope / 2.0 * MAX;
  108.     constant = intercept / slope;
  109.     for (i = 0; i <= MAX; i++) {
  110.       z = constant * constant + 2.0 / slope * distr[i];
  111.       if (z < 0.0)
  112.         z = 0.0;                /* due to quantization error */
  113.       transform[i] = (unsigned char) (-constant + 0.5 - sqrt (z));
  114.     }
  115.     break;
  116.  
  117.   case 0:                      /* histogram equalization */
  118.     constant = ((double) MAX) / ntotal;
  119.     for (i = 0; i <= MAX; i++)
  120.       transform[i] = (unsigned char) (constant * distr[i] + 0.5);
  121.     break;
  122.  
  123.   case 1:                      /* positive ramp */
  124.     intercept = ntotal / (double) MAX - slope / 2.0 * MAX;
  125.     constant = intercept / slope;
  126.     for (i = 0; i <= MAX; i++) {
  127.       z = constant * constant + 2.0 / slope * distr[i];
  128.       if (z < 0.0)
  129.         z = 0.0;                /* due to quantization error */
  130.       transform[i] = (unsigned char) (-constant + 0.5 + sqrt (z));
  131.     }
  132.   }
  133.  
  134. /* transform each pixel value */
  135.  
  136.   for (i = 0; i < nRow; i++)
  137.     for (j = 0; j < nCol; j++)
  138.       image[i][j] = transform[image[i][j]];
  139.  
  140.   ImageOut (argv[2], imgI);
  141.   return (0);
  142. }
  143.  
  144. /* USAGE:       function gives instructions on usage of program
  145.  *                    usage: usage (flag)
  146.  *              When flag is 1, the long message is given, 0 gives short.
  147.  */
  148.  
  149. int
  150. usage (flag)
  151.      short flag;                /* flag =1 for long message; =0 for short message */
  152. {
  153.  
  154. /* print short usage message or long */
  155.   printf ("USAGE: histramp inimg outimg [-s SLOPE_SIGN] [-L]\n");
  156.   if (flag == 0)
  157.     return (-1);
  158.  
  159.   printf ("\nhistramp transforms image intensity distribution\n");
  160.   printf ("to enhance contrast in dark, medium, or light intensities.\n\n");
  161.   printf ("ARGUMENTS:\n");
  162.   printf ("    inimg: input image filename (TIF)\n");
  163.   printf ("   outimg: output image filename (TIF)\n\n");
  164.   printf ("OPTIONS:\n");
  165.   printf ("  -s SLOPE_SIGN: is a value of -1, 0, or 1, connoting the sign\n");
  166.   printf ("                 of the intensity histogram shape. This increases contrast\n");
  167.   printf ("                 in intensity ranges high (-1), medium (0), or low (1)\n");
  168.   printf ("                 intensity ranges;\n");
  169.   printf ("                 the default SLOPE is 0, which yields uniform contrast\n");
  170.   printf ("                 distribution across all intensities (known as histogram\n");
  171.   printf ("                 equalization)\n");
  172.   printf ("             -L: print Software License for this module\n");
  173.  
  174.   return (-1);
  175. }
  176.  
  177.  
  178. /* INPUT:       function reads input parameters
  179.  *                  usage: input (argc, argv, &slopeSign)
  180.  */
  181.  
  182. #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
  183.  
  184. input (argc, argv, slopeSign)
  185.      int argc;
  186.      char *argv[];
  187.      long *slopeSign;           /* sign of slope of histogram */
  188. {
  189.   long n;
  190.  
  191.   if (argc == 1)
  192.     USAGE_EXIT (1);
  193.   if (argc == 2)
  194.     USAGE_EXIT (0);
  195.  
  196.   *slopeSign = DFLT_SLOPE;
  197.  
  198.   for (n = 3; n < argc; n++) {
  199.     if (strcmp (argv[n], "-s") == 0) {
  200.       if (++n == argc)
  201.         USAGE_EXIT (0);
  202.       *slopeSign = (long) atol (argv[n]);
  203.     }
  204.     else if (strcmp (argv[n], "-L") == 0) {
  205.       print_sos_lic ();
  206.       exit (0);
  207.     }
  208.     else
  209.       USAGE_EXIT (0);
  210.   }
  211.  
  212.   return (0);
  213. }
  214.